#pragma once
#include<iostream>
#include<string>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<memory>
#include<pthread.h>
#include<arpa/inet.h>
#include<netinet/in.h>

#include"Task.hpp"
#include"log.hpp"
#include"ThreadPool.hpp"

using namespace std;

const uint16_t gport = 8080;
const int gback = 5;
enum{USAGE_ERR=1,SOCKET_ERR,BIND_ERR,LISTEN_ERR};

class server
{
public:
    server(const uint16_t port = gport):_port(port),_listensock(-1)
    {}

    void initServer()
    {
        //1.创建socket
        _listensock = socket(AF_INET,SOCK_STREAM,0);
        if(_listensock<0)
        {
            logMessage(FATAL, "create socket error");
            exit(SOCKET_ERR);
        }
        logMessage(NORMAL, "create socket success: %d", _listensock);

        //bind网络信息
        struct sockaddr_in local;
        bzero(&local,sizeof(local));
        local.sin_addr.s_addr = htonl(INADDR_ANY);
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);

        if(bind(_listensock,(struct sockaddr*)&local,sizeof(local))<0)
        {
            logMessage(FATAL,"bind socket error");
            exit(BIND_ERR);
        }
        logMessage(NORMAL,"bind socket success");

        //设置socket为监听状态
        if(listen(_listensock,gback)<0)
        {
            logMessage(FATAL,"listen socket err");
            exit(LISTEN_ERR);
        }
        logMessage(NORMAL,"listen socket success");
    }

    void start()
    {
        
        ThreadPool<Task> pool;
        pool.run();
        logMessage(NORMAL, "Thread init success");

        while(true)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            //sock，和client进行通信的fd
            int sock = accept(_listensock,(struct sockaddr*)&peer,&len);
            if(sock<0)
            {
                logMessage(ERROR,"accept error,next");
                continue;
            }

            //version1 普通版  
            //serviceIO(sock);
            //close(sock);

            //version2  多进程版
            // pid_t pid = fork();
            // if(pid==0)
            // {
            //     close(_listensock);
            //     serviceIO(sock);
            //     close(sock);
            //     exit(0);
            // }
            // close(sock);
            // pid_t ret = waitpid(pid,nullptr,0);
            // if(ret>0)
            // {
            //     cout<<"wait success: "<<ret<<endl;
            // }

            //version3 多线程版

            //version4 线程池版
            pool.push(Task(sock,serviceIO));


        }
    }

    ~server(){}

private:
    uint16_t _port;
    int _listensock;
};